package licence

import (
	"errors"
	"strings"
	"time"
)

/*
激活码签名

机器码 + 日期(短) + 参数(16进制) + 固定码 => md5
*/
func activationCodeSignature(machineCode string, shortDate string, params Parameters, fixedCode string) string {
	machineCode = format(machineCode)
	fixedCode = format(fixedCode)
	shortDate = format(shortDate)
	// log.Println(machineCode, shortDate, params.HexString(), fixedCode)
	signature := signature(machineCode+shortDate+params.str34()+fixedCode, 3)
	signature = format(signature)
	// log.Println(signature)
	return signature
}

/*
生成激活码

	input:
		machineCode: 机器码
		       date: 日期 (Format: 2006-12-03)
		     params: 参数 (Struct: Parameters)
		  fixedCode: 固定码
	output:
		activationCode: 激活码 (XXXX-XXXX-XXXX)
		           err: 异常信息
*/
func CreateActivationCode(machineCode string, date string, params Parameters, fixedCode string) (activationCode string, err error) {

	fixedCode = format(fixedCode)
	machineCode = format(machineCode)

	// 检查机器码格式
	if len(machineCode) != 8 {
		err = errors.New("machine code is error")
		return
	}

	// 检查日期格式
	if !VerifyDate(date) {
		err = errors.New("date is error")
		return
	}

	// 检查固定码
	if len(fixedCode) == 0 {
		err = errors.New("fixed code is empty")
		return
	}

	// 生成校验码
	signature := activationCodeSignature(machineCode, shortDate(date), params, fixedCode)

	// 激活码
	activationCode = strings.Join([]string{shortDate(date), params.str34(), signature}, "-")

	return
}

/*
在生产服务器上验证激活码

	input:
		activationcode: 激活码
		     fixedcode: 固定码
	output:
		    status: 激活状态
		      date: 到期日期
		parameters: 参数
		       err: 异常信息
*/
func CheckActivationCode(activationCode string, fixedCode string) (status bool, date string, parameters Parameters, err error) {
	fixedCode = format(fixedCode)

	machineCode := GetMachineCode(fixedCode)
	machineCode = format(machineCode)

	activationCode = format(activationCode)
	shortDate := activationCode[:3]
	params := activationCode[3 : len(activationCode)-3]
	signature := activationCode[len(activationCode)-3:]

	date = longDate(shortDate)
	if expired(date) {
		err = errors.New("date is expired")
		return
	}

	parameters, err = parseParameters(params)
	if err != nil {
		return
	}

	// 验证签名
	if signature != activationCodeSignature(machineCode, shortDate, parameters, fixedCode) {
		err = errors.New("signature verification failed")
		return
	}

	status = true

	return
}

/*
验证激活码中的日期是否过期

	parameters:
		date: 激活码中的日期
	return:
		expired: 过期(true), 没有过期(false)
*/
func expired(date string) bool {
	// 激活码中的日期
	d1, err := time.Parse(DateFormat, date)
	if err != nil {
		return true
	}
	// 当前
	d2, err := time.Parse(DateFormat, time.Now().Format(DateFormat))
	if err != nil {
		return true
	}
	// 比对日期
	if d1.Before(d2) {
		return true
	}
	return false
}
